using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Channels;


namespace SlasheneFramework.WCF
{
	public class ListenUriBindingElement : BindingElement
	{
		public ListenUriBindingElement()
		{
		}
		public ListenUriBindingElement(Uri listenUriBaseAddress)
		{
			this.listenUriBaseAddress = listenUriBaseAddress;

		}
		public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
		{
			if(listenUriBaseAddress != null)
				context.ListenUriBaseAddress = listenUriBaseAddress;
			return base.BuildChannelListener<TChannel>(context);
		}

		public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
		{
			if(listenUriBaseAddress != null)
				context.ListenUriBaseAddress = listenUriBaseAddress;
			return base.BuildChannelFactory<TChannel>(context);
		}

		public override BindingElement Clone()
		{
			return new ListenUriBindingElement(listenUriBaseAddress);
		}
		public override T GetProperty<T>(BindingContext context)
		{
			return context.GetInnerProperty<T>();
		}
		public Uri ListenUriBaseAddress
		{
			get
			{
				return listenUriBaseAddress;
			}
			set
			{
				listenUriBaseAddress = value;
			}
		}

		private Uri listenUriBaseAddress;
	}

	public class ReplyToBindingElement : BindingElement
	{
		public override BindingElement Clone()
		{
			return new ReplyToBindingElement();
		}

		public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
		{
			if(!CanBuildChannelFactory<TChannel>(context))
			{
				throw new ArgumentException("Impossible to build ReplyToBindingElement");
			}
			return (IChannelFactory<TChannel>)new ReplyToChannelFactory(context.ListenUriBaseAddress, (IChannelFactory<IOutputChannel>)base.BuildChannelFactory<TChannel>(context));
		}

		public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
		{
			return base.BuildChannelListener<TChannel>(context);
		}

		public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
		{
			return typeof(TChannel) == typeof(IOutputChannel);
		}

		public override T GetProperty<T>(BindingContext context)
		{
			return context.GetInnerProperty<T>();
		}
	}
}
